/*
	calcserver.c

	Example calculator service in C

	Compilation in C (see samples/calc/calc.h):
	$ soapcpp2 -c calc.h
	$ cc -o calcserver calcserver.c stdsoap2.c soapC.c soapServer.c

--------------------------------------------------------------------------------
gSOAP XML Web services tools
Copyright (C) 2001-2008, Robert van Engelen, Genivia, Inc. All Rights Reserved.
This software is released under one of the following two licenses:
GPL or Genivia's license for commercial use.
--------------------------------------------------------------------------------
GPL license.

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA

Author contact information:
engelen@genivia.com / engelen@acm.org
--------------------------------------------------------------------------------
A commercial use license is available from Genivia, Inc., contact@genivia.com
--------------------------------------------------------------------------------
*/

#include "soapH.h"
#include "login.nsmap"
#include <dirent.h>  

char gstrAllUrl[4096];

int http_get(struct soap * soap);
int GetAllUrl(char *ppstrAllUrl);
int TrimSpace(char *lstrStr);
int TrimWrap(char *lstrStr);
int GetConfigValue(char *ppstrFile,char *ppstrSection,char *ppstrItem,char *ppstrValue);

int main(int argc, char **argv)
{ SOAP_SOCKET m, s; /* master and slave sockets */
  struct soap soap;
  soap_init(&soap);
  if (argc < 2)
    soap_serve(&soap);	/* serve as CGI application */
  else
  { m = soap_bind(&soap, NULL, atoi(argv[1]), 100);
    if (!soap_valid_socket(m))
    { soap_print_fault(&soap, stderr);
      exit(-1);
    }
    
    soap.fget = http_get;
	
	memset(gstrAllUrl,0,sizeof(gstrAllUrl));
	GetAllUrl(gstrAllUrl);
    
    
    fprintf(stderr, "Socket connection successful: master socket = %d\n", m);
    for ( ; ; )
    { s = soap_accept(&soap);
      fprintf(stderr, "Socket connection successful: slave socket = %d\n", s);
      if (!soap_valid_socket(s))
      { soap_print_fault(&soap, stderr);
        exit(-1);
      } 
      soap_serve(&soap);
      soap_end(&soap);
    }
  }
  return 0;
} 

int ns__login(struct soap *soap, char *ppstrUser, char *ppstrPass, double *result)
{ *result = -1;
	if(0==strcmp(ppstrUser,"admin")&&0==strcmp(ppstrPass,"admin"))
		*result=0;
  return SOAP_OK;
} 

int ns__list(struct soap *soap, char *ppstrSection,char **ppstrList)
{ 
	
	if ((*ppstrList = (char*)soap_malloc(soap, strlen(gstrAllUrl)+1)))
    	strcpy(*ppstrList, gstrAllUrl);
    
  	return SOAP_OK;
} 

//get item value from config file
int GetConfigValue(char *ppstrFile,char *ppstrSection,char *ppstrItem,char *ppstrValue)
{
	FILE *lpFp;
	char lstrLine[1024+1];
	char lstrSection[50];
	char lstrItem[50];
	int li;
	char *lpstrPos;
	int liMarkOk=0;
	
	memset(lstrLine,0,sizeof(lstrLine));
	memset(lstrSection,0,sizeof(lstrSection));
	memset(lstrItem,0,sizeof(lstrItem));
	
	lpFp=fopen(ppstrFile,"r");
	if(NULL==lpFp) //如果失败了
	{
		//sprintf(gstrLogBuf,"open %s file fault",ppstrFile);
		//WriteLog(LOG_ERROR,gstrLogBuf);
		return -1;
	}


	while(1)
	{
		memset(lstrLine,0,sizeof(lstrLine));
	
		if(NULL==fgets(lstrLine,1024,lpFp))
			break;
	
		TrimWrap(lstrLine);
		TrimSpace(lstrLine);
		
		lpstrPos=strchr(lstrLine,'#');
		if(NULL!=lpstrPos)
			*lpstrPos=0;
		
		//deal with section
		if(0==liMarkOk)
		{
			sprintf(lstrSection,"[%s]",ppstrSection);
			if(0==strcmp(lstrSection,lstrLine))
			{
				liMarkOk=1;
			}
			continue;
		}

		//deal with item
		lpstrPos=strchr(lstrLine,'=');
		if(NULL==lpstrPos)
			continue;
			
		//get item name
		*lpstrPos=0;
		strcpy(lstrItem,lstrLine);
		TrimSpace(lstrItem);

		if(0!=strcmp(lstrItem,ppstrItem))
		{
			continue;
		}
		*lpstrPos='=';
		strcpy(ppstrValue,lpstrPos+1);
		TrimSpace(ppstrValue);
		liMarkOk=2;
		break;
	}
	
	fclose(lpFp);
	
	if(0==liMarkOk)
		return -2;
	else if(1==liMarkOk)
		return -3;
	
	return 0;
}
	
//remove \r \n at the top and bottom
int TrimWrap(char *lstrStr)
{
	int li=0;
	
	while('\r'==lstrStr[li]||'\n'==lstrStr[li])
	{
		li++;
	}
	
	strcpy(lstrStr,lstrStr+li);
	
	li=strlen(lstrStr)-1;
	
	while('\r'==lstrStr[li]||'\n'==lstrStr[li])
	{
		li--;
	}
	lstrStr[li+1]=0;
	
	return 0;
}

//remove space at the top and bottom
int TrimSpace(char *lstrStr)
{
	int li=0;
	
	while(' '==lstrStr[li])
	{
		li++;
	}
	
	strcpy(lstrStr,lstrStr+li);
	
	li=strlen(lstrStr)-1;
	
	while(' '==lstrStr[li])
	{
		li--;
	}
	lstrStr[li+1]=0;
	
	return 0;
}

int GetAllUrl(char *ppstrAllUrl)
{
	char lstrConfigPath[256];
	char lstrValue[256];
	int li;
	char lstrCamera[10];
	int liRet;
	
	memset(lstrValue,0,sizeof(lstrValue));
	
	ppstrAllUrl[0]=0;
	
	strcpy(lstrConfigPath,"rtspserver.config");
	
	//get camera informtion
	for(li=1;;li++)
	{	
		sprintf(lstrCamera,"camera%d",li);
		
		liRet=GetConfigValue(lstrConfigPath,lstrCamera,"visiturl",lstrValue);
		if(0!=liRet)
		{
			//sprintf(gstrLogBuf,"visiturl is not in %s config file",lstrConfigPath);
	 		//WriteLog(LOG_WARNING,gstrLogBuf);
	 		break;
		}
		
		char lstrType[256];
		liRet=GetConfigValue(lstrConfigPath,lstrCamera,"type",lstrType);
		if(0==strcmp(lstrType,"0"))
		{
			char lstrPath[256];
			liRet=GetConfigValue(lstrConfigPath,lstrCamera,"realurl",lstrPath);
			
			DIR  *pDir ; 
			struct dirent *ent  ; 

			pDir=opendir(lstrPath); 

			while((ent=readdir(pDir))!=NULL) 
			{ 
				if(ent->d_type & DT_DIR) 
				{ 
					;
				} 
				else
				{
					strcat(ppstrAllUrl,lstrValue);
					strcat(ppstrAllUrl,ent->d_name);
					strcat(ppstrAllUrl,"\r\n");
					//cout<<ent->d_name<<endl;
				}
			} 

			continue;
		}

		strcat(ppstrAllUrl,lstrValue);
		strcat(ppstrAllUrl,"\r\n");
	}
	
	return 0;
}


//能够远程读取wsdl文件
int http_get(struct soap * soap)
{ 
    FILE *fd = NULL;

    char *s = strchr(soap->path, '?');
    if (!s || strcmp(s, "?wsdl"))
        return SOAP_GET_METHOD;

    fd = fopen("login.wsdl", "rb");

    if (!fd)
        return 404;

    soap->http_content = "text/xml";

    soap_response(soap, SOAP_FILE);

    for (;;)
    { 
        size_t r = fread(soap->tmpbuf, 1, sizeof(soap->tmpbuf), fd);
        if (!r)
            break;
        if (soap_send_raw(soap, soap->tmpbuf, r))
            break; 
    }

    fclose(fd);
    soap_end_send(soap);

    return SOAP_OK;
}
